package com.wangxiaobao.charge.mylibrary.engine;

import com.wangxiaobao.charge.mylibrary.engine.adapter.BooleanAdapter;
import com.wangxiaobao.charge.mylibrary.engine.adapter.BytesFourToIntAdapter;
import com.wangxiaobao.charge.mylibrary.engine.adapter.StrAdapter;
import com.wangxiaobao.charge.mylibrary.engine.adapter.StringAdapter;
import com.wangxiaobao.charge.mylibrary.request.RequestData;
import com.wangxiaobao.charge.mylibrary.utils.ByteUtil;
import com.wangxiaobao.charge.mylibrary.utils.LogUtil;
import me.jahnen.libaums.core.driver.scsi.ScsiBlockDevice;

import java.util.Arrays;

public class Scsi extends AbsScsi implements IscsiAction {

    public Scsi(ScsiBlockDevice scsiBlockDevice) {
        super(scsiBlockDevice);
    }

    @Override
    public String getSn() throws Exception {
        return send(new RequestData.Builder()
                .opHead(RequestData.OP_HEAD_GET)
                .ctl(Ctl.GET.GTE_SN)
                .payload(new byte[]{0x00})
                .build(), new StringAdapter());
    }

    @Override
    public long getTime() throws Exception {
        return send(new RequestData.Builder()
                .opHead(RequestData.OP_HEAD_GET)
                .ctl(Ctl.GET.GTE_TIME)
                .payload(new byte[]{0x00})
                .build(), new BytesFourToIntAdapter());
    }

    @Override
    public String getRK() throws Exception {
        return send(new RequestData.Builder()
                .opHead(RequestData.OP_HEAD_GET)
                .ctl(Ctl.GET.GTE_RK)
                .payload(new byte[]{0x00})
                .build(), new StringAdapter());
    }

    @Override
    public String getESP() throws Exception {
        //V00.01b01 00:00:00:00:00:00
        String ret= send(new RequestData.Builder()
                .opHead(RequestData.OP_HEAD_GET)
                .ctl(Ctl.GET.GTE_ESP)
                .payload(new byte[]{0x00})
                .build(), new StringAdapter());
        if("V00.01b01".equalsIgnoreCase(ret))
            return getESP();
        else
            return ret;
    }

    @Override
    public String getWIFI() throws Exception {
        return send(new RequestData.Builder()
                .opHead(RequestData.OP_HEAD_GET)
                .ctl(Ctl.GET.GTE_WIFI_NAME)
                .payload(new byte[]{0x00})
                .build(), new StringAdapter());
    }

    @Override
    public void testLight() throws Exception {
        send(new RequestData.Builder()
                .opHead(RequestData.OP_HEAD_GET)
                .ctl(Ctl.GET.TEST_LIGHT)
                .payload(new byte[]{0x00})
                .build(), new StringAdapter());
    }

    @Override
    public String getMac() throws Exception {
        String ret= send(new RequestData.Builder()
                .opHead(RequestData.OP_HEAD_GET)
                .ctl(Ctl.GET.GTE_BLE_MAC)
                .payload(new byte[]{0x00})
                .build(), new StrAdapter());
        if("000000000000".equalsIgnoreCase(ret))
            return getMac();
        else
            return ret;
    }

    @Override
    public String getWifiStatus() throws Exception {
        return send(new RequestData.Builder()
                .opHead(RequestData.OP_HEAD_GET)
                .ctl(Ctl.GET.GTE_WIFI_STATUS)
                .payload(new byte[]{0x00})
                .build(), new StringAdapter());
    }

    @Override
    public String getDeviceModel() throws Exception {
        return send(new RequestData.Builder()
                .opHead(RequestData.OP_HEAD_GET)
                .ctl(Ctl.GET.GTE_DEVICE_MODEL)
                .payload(new byte[]{0x00})
                .build(), new StringAdapter());
    }

    @Override
    public void setTime(long timestamp) throws Exception {
        send(new RequestData.Builder()
                .opHead(RequestData.OP_HEAD_SET)
                .reserved(0x00)
                .ctl(Ctl.SET.SET_TIME)
                .payload(ByteUtil.intToBytesLittle(timestamp/1000l))
                .build(), new BooleanAdapter());
    }

    @Override
    public void setSn(String sn) throws Exception {
        //todo 需要处理分包
        byte[] payload=sn.getBytes();
        int dataLen=payload.length;
        if(dataLen<=11){
            send(new RequestData.Builder()
                    .opHead(RequestData.OP_HEAD_SET)
                    .reserved(0x00)
                    .ctl(Ctl.SET.SET_SN)
                    .payload(payload)
                    .build(), new BooleanAdapter());
        }else{
            int allPack=ByteUtil.getHeight4((byte) dataLen);
            int maxPack=(int)Math.ceil(dataLen * 1.0 /11);
            for (int i=0;i<maxPack;i++){
                int reserved = (maxPack << 4) | (i+1);
                send(new RequestData.Builder()
                        .opHead(RequestData.OP_HEAD_SET)
                        .reserved(reserved)
                        .ctl(Ctl.SET.SET_SN)
                        .payload(Arrays.copyOfRange(payload,i*11,Math.min(dataLen,(i+1)*11)))
                        .build(), new BooleanAdapter());
            }
        }


    }

    @Override
    public void setDeviceModel(int model) throws Exception {
        //todo 设置与返回不一致
        send(new RequestData.Builder()
                .opHead(RequestData.OP_HEAD_SET)
                .reserved(0x00)
                .ctl(Ctl.SET.SET_DEVICE_MODEL)
                .payload(model==1?new byte[]{0x31}:new byte[]{0x30})
                .build(), new BooleanAdapter());
    }

    @Override
    public void setLight(int model) throws Exception {
        send(new RequestData.Builder()
                .opHead(RequestData.OP_HEAD_SET)
                .reserved(0x00)
                .ctl(Ctl.SET.SET_LIGHT)
                .payload(model==1?new byte[]{0x31}:new byte[]{0x30})
                .build(), new BooleanAdapter());
    }

    @Override
    public void setWifiSwitch(int model) throws Exception {
        send(new RequestData.Builder()
                .opHead(RequestData.OP_HEAD_SET)
                .reserved(0x00)
                .ctl(Ctl.SET.SET_OPEN_OR_CLOSE_WIFI)
                .payload(model==1?new byte[]{0x31}:new byte[]{0x30})
                .build(), new BooleanAdapter());
    }

    @Override
    public void reboot() throws Exception {
        send(new RequestData.Builder()
                .opHead(RequestData.OP_HEAD_SET)
                .reserved(0x00)
                .ctl(Ctl.SET.SET_REBOOT)
                .payload(new byte[]{0x00})
                .build(), new BooleanAdapter());
    }

    @Override
    public void recovery() throws Exception {
        send(new RequestData.Builder()
                .opHead(RequestData.OP_HEAD_SET)
                .reserved(0x00)
                .ctl(Ctl.SET.SET_RECOVERY)
                .payload(new byte[]{0x00})
                .build(), new BooleanAdapter());
    }

    @Override
    public void connectWifi(String ssid, String password) throws Exception {
        //todo 需要处理分包
        byte[] payload=(ssid+","+password).getBytes();
        int dataLen=payload.length;
        if(dataLen<=11){
            send(new RequestData.Builder()
                    .opHead(RequestData.OP_HEAD_SET)
                    .ctl(Ctl.SET.SET_CONNECT_WIFI)
                    .reserved(0x00)
                    .payload(payload)
                    .build(), new BooleanAdapter());
        }else{
//            int allPack=ByteUtil.getHeight4((byte) dataLen);
            int maxPack=(int)Math.ceil(dataLen * 1.0 /11);
            for (int i=0;i<maxPack;i++){
                int reserved = (maxPack << 4) | (i+1);
                send(new RequestData.Builder()
                        .opHead(RequestData.OP_HEAD_SET)
                        .reserved(reserved)
                        .ctl(Ctl.SET.SET_CONNECT_WIFI)
                        .payload(Arrays.copyOfRange(payload,i*11,Math.min(dataLen,(i+1)*11)))
                        .build(), new BooleanAdapter());
            }
        }
    }

    @Override
    public void disconnectWifi(String ssid) throws Exception {
        //todo 需要处理分包
        byte[] payload=ssid.getBytes();
        int dataLen=payload.length;
        if(dataLen<=11){
            send(new RequestData.Builder()
                    .opHead(RequestData.OP_HEAD_SET)
                    .reserved(0x00)
                    .ctl(Ctl.SET.SET_DISCONNECT_WIFI)
                    .payload(payload)
                    .build(), new BooleanAdapter());
        }else{
            int allPack=ByteUtil.getHeight4((byte) dataLen);
            int maxPack=(int)Math.ceil(dataLen * 1.0 /11);
            for (int i=0;i<maxPack;i++){
                int reserved = (maxPack << 4) | (i+1);
                send(new RequestData.Builder()
                        .opHead(RequestData.OP_HEAD_SET)
                        .reserved(reserved)
                        .ctl(Ctl.SET.SET_DISCONNECT_WIFI)
                        .payload(Arrays.copyOfRange(payload,i*11,Math.min(dataLen,(i+1)*11)))
                        .build(), new BooleanAdapter());
            }
        }
    }
}
